home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
qex
/
qexsndcd
/
cwmon.dsp
< prev
next >
Wrap
Text File
|
1994-07-06
|
9KB
|
276 lines
{ --------------------------------------------------------------------- }
{ Super Simple DSP bootstrap monitor for testing the CW filter }
{ Demo software accompanying the QEX August 1994 article: }
{ "Programming a DSP PC Sound Card for Amateur Radio" }
{ (c) Johan Forrer, KC7WW }
{ 26553 Priceview Drive }
{ Monroe, OR 97456 }
{ --------------------------------------------------------------------- }
{ Acknowlegements to: }
{ Joe Ballantyne, Echo Speech Corporation }
{ DSP Applications Group, Analog Devices }
{ --------------------------------------------------------------------- }
{ }
{ Compilation instructions: }
{ >spasm21 cwmon.dsp }
{ >cload cwmon }
{ }
{ --------------------------------------------------------------------- }
{ Monitor version number }
{ returned when monitor is initialized }
.CONST version = 0x0100; { msb byte represents integer value }
{ lsb byte represents a decimal value }
{ from .01 to .99 }
{ --------------------------------------------------------------------- }
{ List of implemented call and answer functions }
{ --------------------------------------------------------------------- }
{ CODE Function }
{ -------------------- }
{ 0x00b0 - Start timer }
{ 0x00b1 - End timer }
{ 0x00b4 - Start application }
{ 0x00b5 - End application }
{ 0x00d0 - Read Dm location }
{ 0x00d1 - Write Dm location }
{ 0x00d2 - Read Pm location }
{ 0x00d3 - Write Pm location }
{ 0x00d4 - Send back "PSA-MON" string }
{ --------------------------------------------------------------------- }
{ The folling are a number of useful addresses }
.const PSS_data_reg =0x3000;
.const PSS_control_reg =0x3008;
.const PSS_status_reg =0x3008;
.const PSS_dma_reg =0x3010;
.const ram_bank_reg =0x3018;
.const ext_mem_latch =0x3020;
.const addr_1848 =0x3440;
.const data_1848 =0x3448;
.const stat_1848 =0x3450;
.const pio_1848 =0x3458;
.const IRQ_status =0x31C0;
.const dmal_1848 =0x3060;
.const dmar_1848 =0x3068;
.const enable_1848 =0x3070;
.const system_control =0x3FFF;
.const wait_state_ctl =0x3FFE;
.const timer_period =0x3FFD;
.const timer_counter =0x3FFC;
.const timer_prescale =0x3FFB;
{ Note: delay lines use circular addressing }
{ 9- 16 requires a " 16=0x0010" boundary }
{ length 17- 32 requires a " 32=0x0020" boundary }
{ 33- 64 requires a " 64=0x0040" boundary }
{ 65-128 requires a "128=0x0080" boundary }
{ 129-256 requires a "256=0x0100" boundary }
{ Here we define the start address of our DSP application that }
{ incidentally are embedded in the AD1848 sound port ISR }
.const sound_port =0x0100; { ISR is at 0100 }
{ Define space for the FIR bandpass filter delay line }
.const BPFI =0x3800; { 3800 -> Input bandpass }
{--------------------INTERRUPT VECTORS--------------------------------------}
jump main_; nop; nop; nop; { 0000 restart interrupt}
jump sound_port; nop; nop; nop; { 0004 IRQ2 interrupt}
rti; nop; nop; nop; { 0008 SPORT0 tx interrupt}
rti; nop; nop; nop; { 000C SPORT0 rx interrupt}
rti; nop; nop; nop; { 0010 IRQ1 or SPORT1 tx}
rti; nop; nop; nop; { 0014 pc_irq_vec }
jump timer_int;nop;nop;nop; { 0018 Timer interrupt }
{ ************************************************************************** }
main_:
ax0 = dm(PSS_data_reg); { dummy read to clear out last boot byte}
ax1 = version; { send version number to PC}
call put_word_;
ax0 = 0x0007; { no nesting of interrupts }
ICNTL=ax0; { all interupts EDGE sensitive }
ax0 = 0xFFFF; { for max length Timer period }
dm(timer_period) = ax0;
ax0 = 0x00FF;
dm(timer_prescale) = ax0; { Max Timer prescale}
ax0 = 0x0011; { enable timer and IRQ2 interrupts - for DMA}
IMASK = ax0;
l0=0;l1=0;l2=0;l3=0; { all length (modulo) registers }
l4=0;l5=0;l6=0;l7=0; { should be set to 0 }
m0=0;m1=1;m2=0;m3=-1; { modify registers set ( DAG1 set) }
m4=0;m5=1;m6=0;m7=-1; { to various constants ( DAG2 set) }
ax0=0x2000;
dm(wait_state_ctl)=ax0; { set 2 wait states- Sound port }
{ zero wait states for everything else }
ax0=dm(system_control); { read the system control register}
ay0=0xfff8;
ar=ax0 and ay0; { make program mem 0 wait state}
dm(system_control)=ar;
ax0 = 0x2000; { set SPWE (bit 13) in IRQ enable register }
dm(IRQ_status)=ax0; { to allow DMA interrupts }
{---------------------------------------------------------------------------}
{ Start looking for a call and answer command }
loop_:
call get_word_;
ay0=0x00d0; { Dm read }
ar=ax0 xor ay0;
if eq jump data_read_;
ay0=0x00d1; { Dm write }
ar=ax0 xor ay0;
if eq jump data_write_;
ay0=0x00d2; { Pm read }
ar=ax0 xor ay0;
if eq jump program_read_;
ay0=0x00d3; { Pm write }
ar=ax0 xor ay0;
if eq jump program_write_;
ay0=0x00d4; { Send back PSA-MON string }
ar=ax0 xor ay0;
if eq jump prog_id_write_;
ay0=0x00b4; { Start application }
ar=ax0 xor ay0;
if eq jump start_app;
ay0=0x00b5; { End application }
ar=ax0 xor ay0;
if eq jump end_app;
ay0=0x00b0; { Start timer }
ar=ax0 xor ay0;
if eq jump start_timer;
ay0=0x00b1; { Stop timer }
ar=ax0 xor ay0;
if eq jump stop_timer;
jump loop_;
{---------------------------------------------------------------------------}
{ Timer ISR }
{ Assert PC interrupt }
timer_int:
ena sec_reg;
ax0=0x1000;
dm(PSS_control_reg)=ax0;
dis sec_reg;
rti;
{---------------------------------------------------------------------------}
{ Call and Answer functions }
data_read_:
call get_word_;
i6 = ax0;
ax1 = dm(i6,m6); { m6=0 }
call put_word_;
jump loop_;
data_write_:
call get_word_;
i6 = ax0;
call get_word_;
dm(i6,m6)=ax0;
jump loop_;
program_read_:
call get_word_;
i6 = ax0;
ax1 = pm(i6,m6);
call put_word_;
ax1 = px;
call put_word_;
jump loop_;
program_write_:
call get_word_;
i6 = ax0;
call get_word_;
px = ax0;
call get_word_;
pm(i6,m6)=ax0;
jump loop_;
prog_id_write_:
ax1=0x0050; { P }
call put_word_;
ax1=0x0053; { S }
call put_word_;
ax1=0x0041; { A }
call put_word_;
ax1=0x002D; { - }
call put_word_;
ax1=0x004D; { M }
call put_word_;
ax1=0x004F; { O }
call put_word_;
ax1=0x004E; { N }
call put_word_;
ax1=0x0000;
call put_word_;
jump loop_;
get_word_:
ay0=0x4000;
ax0=dm(PSS_status_reg);
gwloop:
ar=ax0 and ay0;
ax0=dm(PSS_status_reg);
if eq jump gwloop;
ax0=dm(PSS_data_reg);
rts;
put_word_:
ax0=dm(PSS_status_reg);
ay0=0x8000;
ar=ax0 and ay0;
if eq jump put_word_;
dm(PSS_data_reg) = ax1;
rts;
{ Stop/Start TIMER -------------------------------------------------------- }
start_timer:
ENA TIMER;
jump loop_;
stop_timer:
DIS TIMER;
jump loop_;
{ Start/Stop application ------------------------------------------------ }
start_app:
ax0=0xFFFF;
dm(enable_1848)=ax0; { Let DSP access 1848 }
i1=BPFI; { Pointers and lengths }
l1=127;
ax0 = 0x0021; { enable IRQ2 interrupts - for DMA}
IMASK = ax0; { enable TIMER interrupts too }
jump loop_;
end_app:
ax0 = 0x0000; { disable IRQ2 interrupts - for DMA}
IMASK = ax0;
ax0=0x0000; { get ready to return to the PC }
dm(enable_1848)=ax0; { Now let PC access 1848 }
jump loop_;
{---------------------------------------------------------------------------}